added samples
[windows-sources.git] / sdk / samples / all in on code / Visual Studio 2008 / ATLShellExtPropSheetHandler / FilePropSheetExt.cpp
blob05b97ca2b1627de7fe818894a3a578bc3497b096
1 /****************************** Module Header ******************************\
2 * Module Name: FilePropSheetExt.cpp
3 * Project: ATLShellExtPropSheetHandler
4 * Copyright (c) Microsoft Corporation.
5 *
6 * The implementation of CFilePropSheetExt for the FilePropSheet property
7 * sheet handler. FilePropSheetExt adds a property page with the subject
8 * "All-In-One Code Framework" to the property dialogs of all file classes in
9 * Windows Explorer. The property page displays the name of the first selected
10 * file. It also has a button "Simulate Property Changing" to simulate the
11 * change of properties that activates the "Apply" button of the property
12 * sheet.
14 * This source is subject to the Microsoft Public License.
15 * See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
16 * All other rights reserved.
18 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
19 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
21 \***************************************************************************/
23 #pragma region Includes
24 #include "stdafx.h"
25 #include "FilePropSheetExt.h"
26 #pragma endregion
29 INT_PTR CALLBACK FilePropPageDlgProc(HWND, UINT, WPARAM, LPARAM);
30 UINT CALLBACK FilePropPageCallbackProc(HWND, UINT, LPPROPSHEETPAGE);
33 /////////////////////////////////////////////////////////////////////////////
34 // CFilePropSheetExt IShellExtInit methods.
35 //
38 // FUNCTION: CFilePropSheetExt::Initialize(LPCITEMIDLIST, LPDATAOBJECT,
39 // HKEY)
41 // PURPOSE: Initializes a property sheet extension, shortcut menu extension,
42 // or drag-and-drop handler.
44 IFACEMETHODIMP CFilePropSheetExt::Initialize(
45 LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hProgID)
47 if (NULL == pDataObj)
49 return E_INVALIDARG;
52 FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
53 STGMEDIUM stm;
55 // pDataObj contains the objects being acted upon. In this example,
56 // we get an HDROP handle for enumerating the selected files.
57 if (FAILED(pDataObj->GetData(&fe, &stm)))
58 return E_INVALIDARG;
60 // Get an HDROP handle.
61 HDROP hDrop = (HDROP)GlobalLock(stm.hGlobal);
62 if (NULL == hDrop)
64 ReleaseStgMedium(&stm);
65 return E_INVALIDARG;
68 // Determine how many files are involved in this operation
69 UINT nFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
70 if (nFiles == 0)
72 GlobalUnlock(stm.hGlobal);
73 ReleaseStgMedium(&stm);
74 return E_INVALIDARG;
77 // Get the name of the first file and store it in m_szFileName
78 if (0 == DragQueryFile(hDrop, 0, m_szFileName, MAX_PATH))
80 GlobalUnlock(stm.hGlobal);
81 ReleaseStgMedium(&stm);
82 return E_INVALIDARG;
85 // [-or-]
87 // Enumerates through the selected files and directories
88 //TCHAR szFileName[MAX_PATH];
89 //for (UINT i = 0; i < nFiles; i++)
90 //{
91 // // Get the next filename
92 // if (0 == DragQueryFile(hDrop, i, szFileName, MAX_PATH))
93 // continue;
95 // //...
96 //}
98 // Release resources
99 GlobalUnlock(stm.hGlobal);
100 ReleaseStgMedium(&stm);
102 // If any value other than S_OK is returned from
103 // IShellExtInit::Initialize, the context menu is not displayed.
104 return S_OK;
108 /////////////////////////////////////////////////////////////////////////////
109 // CFilePropSheetExt IShellPropSheetExt methods.
113 // FUNCTION: CFilePropSheetExt::AddPages(LPFNADDPROPSHEETPAGE, LPARAM)
115 // PURPOSE: Adds one or more pages to a property sheet that the Shell
116 // displays for a file object. The Shell calls this method for
117 // each property sheet handler registered to the file type.
119 IFACEMETHODIMP CFilePropSheetExt::AddPages(
120 LPFNADDPROPSHEETPAGE lpfnAddPageProc, LPARAM lParam )
122 PROPSHEETPAGE psp;
123 HPROPSHEETPAGE hPage;
125 // Set up the PROPSHEETPAGE struct
126 ZeroMemory(&psp, sizeof(PROPSHEETPAGE));
127 psp.dwSize = sizeof(PROPSHEETPAGE);
128 psp.dwFlags = PSP_USETITLE | PSP_USECALLBACK;
129 psp.hInstance = _AtlBaseModule.GetResourceInstance();
130 psp.pszTemplate = MAKEINTRESOURCE(IDD_FILE_PROPPAGE);
131 psp.pszIcon = NULL;
132 psp.pszTitle = _T("All-In-One Code Framework");
133 psp.pfnDlgProc = (DLGPROC)FilePropPageDlgProc;
134 psp.pcRefParent = NULL;
135 psp.pfnCallback = FilePropPageCallbackProc;
136 // Pass the object pointer to the property page
137 psp.lParam = (LPARAM)this;
139 // Create a property sheet page and get the handle.
140 hPage = CreatePropertySheetPage(&psp);
142 if (hPage)
144 // The property page is then added to the property sheet by calling
145 // the callback function passed to IShellPropSheetExt::AddPages in
146 // the lpfnAddPage parameter.
147 if (lpfnAddPageProc(hPage, lParam))
149 // By default, after AddPages returns, the shell releases its
150 // IShellPropSheetExt interface and the property page cannot
151 // access the extension object. However, it is sometimes desirable
152 // to be able to use the extension object, or some other object,
153 // from the property page. So we increase the reference count and
154 // maintain this object until the page is released in
155 // PropPageCallbackProc where we call Release upon the extension.
156 this->AddRef();
158 else
160 DestroyPropertySheetPage(hPage);
161 return E_FAIL;
164 else
166 return E_OUTOFMEMORY;
169 // If any value other than S_OK is returned from
170 // IShellPropSheetExt::AddPages, the property sheet is not displayed.
171 return S_OK;
175 /////////////////////////////////////////////////////////////////////////////
176 // CFilePropSheetExt dialog/callback procs
179 #define THIS_POINTER_PROP _T("ThisPointerProperty")
183 // FUNCTION: OnInitFilePropPageDialog(HWND, HWND, LPARAM)
185 // PURPOSE: Process the WM_INITDIALOG message of the property page.
187 BOOL OnInitFilePropPageDialog(HWND hWnd, HWND hWndFocus, LPARAM lParam)
189 // Get the pointer to the object. This is contained in the LPARAM of
190 // the PROPSHEETPAGE structure.
191 LPPROPSHEETPAGE pPage = (LPPROPSHEETPAGE)lParam;
192 if (pPage)
194 // Access the property sheet extension from property page
195 CFilePropSheetExt* pPropSheetExt = (CFilePropSheetExt*)pPage->lParam;
196 if (pPropSheetExt)
198 HWND hFileName = GetDlgItem(hWnd, IDC_FILENAME_STATIC);
199 SetWindowText(hFileName, pPropSheetExt->m_szFileName);
201 // Store the object pointer with this particular page dialog.
202 SetProp(hWnd, THIS_POINTER_PROP, (HANDLE)pPropSheetExt);
206 return TRUE;
211 // FUNCTION: OnFilePropPageApply(HWND, PSHNOTIFY*)
213 // PURPOSE: OnFilePropPageApply is called for the property page when user
214 // clicks on the Apply or OK button on the property sheet.
216 BOOL OnFilePropPageApply(HWND hWnd, PSHNOTIFY* phdr)
218 // Get the property sheet extension object pointer that was stored
219 // in the page dialog. (see OnInitPropPageDialog)
220 CFilePropSheetExt *pPropSheetExt = (CFilePropSheetExt*)GetProp(hWnd,
221 THIS_POINTER_PROP);
223 // Access the property sheet extension object
224 // ...
226 // Return PSNRET_NOERROR to allow the property dialog to close if the
227 // user clicked OK
228 SetWindowLong(hWnd, DWL_MSGRESULT, PSNRET_NOERROR);
230 return TRUE;
235 // FUNCTION: OnFilePropPageDestroy(HWND)
237 // PURPOSE: Process the WM_DESTROY message of the property page.
239 void OnFilePropPageDestroy(HWND hWnd)
241 // Remove the property from the page.
242 RemoveProp(hWnd, THIS_POINTER_PROP);
247 // FUNCTION: FilePropPageDlgProc(HWND, UINT, WPARAM, LPARAM)
249 // PURPOSE: Processes messages for the property page.
251 INT_PTR CALLBACK FilePropPageDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam,
252 LPARAM lParam)
254 switch (uMsg)
256 case WM_INITDIALOG:
257 return OnInitFilePropPageDialog(hWnd, (HWND)wParam, lParam);
259 case WM_COMMAND:
261 switch (LOWORD(wParam))
263 case IDC_CHANGEFILEPROP_BN:
264 // Simulate property changing.
265 // Inform the property sheet to enable the Apply button
266 SendMessage(GetParent(hWnd), PSM_CHANGED, (WPARAM)hWnd, 0);
267 return TRUE;
269 break;
272 case WM_NOTIFY:
274 switch (((LPNMHDR)lParam)->code)
276 case PSN_APPLY:
277 return OnFilePropPageApply(hWnd, (PSHNOTIFY*)lParam);
279 break;
282 case WM_DESTROY:
283 OnFilePropPageDestroy(hWnd);
284 return TRUE;
287 return FALSE; // Let system deal with other messages
292 // FUNCTION: FilePropPageCallbackProc(HWND, UINT, LPPROPSHEETPAGE)
294 // PURPOSE: Specifies an application-defined callback function that a
295 // property sheet calls when a page is created and when it is
296 // about to be destroyed. An application can use this function to
297 // perform initialization and cleanup operations for the page.
299 UINT CALLBACK FilePropPageCallbackProc(HWND hWnd, UINT uMsg,
300 LPPROPSHEETPAGE ppsp)
302 switch(uMsg)
304 case PSPCB_CREATE:
305 // Must return TRUE to enable the page to be created.
306 return TRUE;
308 case PSPCB_RELEASE:
310 // Release the property sheet extension object. This is called
311 // even if the property page was never actually displayed.
312 CFilePropSheetExt *pPropSheetExt = (CFilePropSheetExt*)ppsp->lParam;
314 if (pPropSheetExt != NULL)
316 pPropSheetExt->Release();
319 break;
322 return FALSE;